package com.zydl.f9164m.util;

import com.clj.fastble.utils.BleLog;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import my.ByteUtils;
import my.FileUtils;

public class MessageUtil {

    private static byte[] fileContent;
    private static List<byte[]> splitFileDataList;
    private static int fileTotal;  //文件中包数

    public static byte[] getUpgradeNotice(String path) {
        File file = new File(path);
//        BleLog.d("文件大小==="+file.length());
//        BleLog.d("文件大小long转byte==="+ ByteUtils.longToByteArray(file.length()));
//        BleLog.d("文件总包数(284KB/200B(每包暂定最大大小为200字节))==="+ (int)Math.ceil(file.length()/200d));
//        BleLog.d("文件总包数==="+ByteUtils.intToByteArray((int) Math.ceil(file.length()/200d)) );
//        BleLog.d("文件crc32码==="+FileUtils.getCRC32(path));
//        BleLog.d("文件crc32码String转byte==="+FileUtils.getCRC32(path).getBytes());

        byte[] data = new byte[3];
        data[0] = (byte) 0xfe;          //head(1)

        byte[] fileSize = new byte[4];
        fileSize = ByteUtils.long2byte(file.length());

        byte[] packetTotal = new byte[2];
        fileTotal = (int) Math.ceil(file.length() / 200d);
        packetTotal = ByteUtils.int2byte(fileTotal);

        byte[] crc16 = new byte[2];
        fileContent = FileUtils.readFileToByteArray(path);
        crc16 = CRC16Util.getCrc16(fileContent);

        data[1] = (byte) (1 + fileSize.length + packetTotal.length + crc16.length);            //len(1)  长度
        data[2] = (byte) 0x4e;             //fc(1)  功能码

        byte[] payload = byteMerger(fileSize, packetTotal, crc16);
        data = byteMerger(data, payload);

        byte[] cs = new byte[1];
        cs[0] = getXor(1, data.length, data);

        data = byteMerger(data, cs);

        byte[] end = new byte[1];
        end[0] =  (byte) 0xfe;

        data = byteMerger(data, end);
        return data;
    }

    public static byte[] byteMerger(byte[]... bytes) {
        List<Byte> byteList = new ArrayList<>();
        for (int i = 0; i < bytes.length; i++) {
            for (byte bt : bytes[i]) {
                byteList.add(bt);
            }
        }

        byte[] returnByte = new byte[byteList.size()];
        for (int i = 0; i < byteList.size(); i++) {
            returnByte[i] = byteList.get(i);
        }

        return returnByte;
    }

    public static byte getXor(int start, int end, byte[]... bytes) {
        List<Byte> byteList = new ArrayList<>();
        for (int i = 0; i < bytes.length; i++) {
            for (byte bt : bytes[i]) {
                byteList.add(bt);
            }
        }
        byte temp = 0;
        for (int j = 0; j < byteList.size(); j++) {
            if (j != 0)
                temp ^= byteList.get(j);
        }
        return temp;
    }



    public static byte[] sendFileData(int packetIndexs) {
        BleLog.d("报文返回=当前要发送的请求包索引=" + packetIndexs);
        byte[] data = new byte[3];
        if (packetIndexs <=fileTotal){
            data[0] = (byte) 0xfe;          //head(1)

            //当前升级包索引
            byte[] packetIndex = new byte[2];
            packetIndex = ByteUtils.int2byte(packetIndexs);


            // 当前升级包的大小
            splitFileDataList = splitAry2(fileContent,200);
            byte[] packetSize = new byte[2];
            packetSize = ByteUtils.int2byte(splitFileDataList.get(packetIndexs).length);

            byte[] packetCrc16 = new byte[2];
            packetCrc16 = CRC16Util.getCrc16(splitFileDataList.get(packetIndexs));

            byte[] filePacketData = new byte[splitFileDataList.get(packetIndexs).length];
            filePacketData = splitFileDataList.get(packetIndexs);

            data[1] = (byte) (1 + packetIndex.length+packetSize.length+packetCrc16.length+filePacketData.length);            //len(1)  长度
            data[2] = (byte) 0x46;             //fc(1)  功能码

            byte[]  payload = byteMerger(packetIndex,packetSize,packetCrc16,filePacketData);
            data = byteMerger(data,payload);

            byte[] cs = new byte[1];
            cs[0] = getXor(1, data.length, data);

            data = byteMerger(data, cs);
            packetIndexs++;
        }

        byte[] end = new byte[1];
        end[0] =  (byte) 0xfe;

        data = byteMerger(data, end);
        return data;
    }


    public static Object[] splitAry(byte[] ary, int subSize) {
        int count = ary.length % subSize == 0 ? ary.length / subSize : ary.length / subSize + 1;
        List<List<Byte>> subAryList = new ArrayList<List<Byte>>();

        for (int i = 0; i < count; i++) {
            int index = i * subSize;
            List<Byte> list = new ArrayList<Byte>();
            int j = 0;
            while (j < subSize && index < ary.length) {
                list.add(ary[index++]);
                j++;
            }
            subAryList.add(list);
        }
        Object[] subAry = new Object[subAryList.size()];
        for (int i = 0; i < subAryList.size(); i++) {
            List<Byte> subList = subAryList.get(i);
            byte[] subAryItem = new byte[subList.size()];
            for (int j = 0; j < subList.size(); j++) {
                subAryItem[j] = subList.get(j);
            }
            subAry[i] = subAryItem;
        }

        return subAry;
    }


    public static List<byte[]> splitAry2(byte[] ary, int subSize) {
        int count = ary.length % subSize == 0 ? ary.length / subSize : ary.length / subSize + 1;
        List<List<Byte>> subAryList = new ArrayList<List<Byte>>();

        for (int i = 0; i < count; i++) {
            int index = i * subSize;
            List<Byte> list = new ArrayList<Byte>();
            int j = 0;
            while (j < subSize && index < ary.length) {
                list.add(ary[index++]);
                j++;
            }
            subAryList.add(list);
        }
        List<byte[]> subAry = new ArrayList<>();
        for (int i = 0; i < subAryList.size(); i++) {
            List<Byte> subList = subAryList.get(i);
            byte[] subAryItem = new byte[subList.size()];
            for (int j = 0; j < subList.size(); j++) {
                subAryItem[j] = subList.get(j);
            }
            subAry.add(subAryItem);
        }

        return subAry;
    }


    public static int getFileTotal() {
        return fileTotal;
    }

    public static void setFileTotal(int fileTotal) {
        MessageUtil.fileTotal = fileTotal;
    }

}
